package java8;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureTests {


    public static class CheckRecipeInputDTO {
        public List<RecipeDTO> recipes;

        public List<RecipeDTO> getRecipes() {
            return recipes;
        }

        public void setRecipes(List<RecipeDTO> recipes) {
            this.recipes = recipes;
        }
    }

    public static class RecipeDTO {
        public List<String> details;

        public List<String> getDetails() {
            return details;
        }

        public void setDetails(List<String> details) {
            this.details = details;
        }
    }


    public static void main(String[] args) throws InterruptedException, ExecutionException {
       /* List<String> details1 = new ArrayList<>();
        details1.add("d11");
        details1.add("d12");

        List<String> details2 = new ArrayList<>();
        details2.add("d21");
        details2.add("d22");
        details2.add("d23");
        details2.add("d24");
        details2.add("d24");

        List<String> details3 = new ArrayList<>();
        details3.add("d31");
        details3.add("d32");
        details3.add("d33");

        RecipeDTO recipeDTO1 = new RecipeDTO();
        RecipeDTO recipeDTO2 = new RecipeDTO();
        RecipeDTO recipeDTO3 = new RecipeDTO();

        recipeDTO1.setDetails(details1);
        recipeDTO2.setDetails(details2);
        recipeDTO3.setDetails(details3);

        List<RecipeDTO> recipeDTOS1 = new ArrayList<>();
        recipeDTOS1.add(recipeDTO1);
        List<RecipeDTO> recipeDTOS2 = new ArrayList<>();
        recipeDTOS1.add(recipeDTO2);
        List<RecipeDTO> recipeDTOS3 = new ArrayList<>();
        recipeDTOS1.add(recipeDTO3);

        CheckRecipeInputDTO checkRecipeInputDTO = new CheckRecipeInputDTO();
        checkRecipeInputDTO.setRecipes(recipeDTOS1);
        System.out.println("l1:" + checkRecipeInputDTO.getRecipes().size() + ", " + checkRecipeInputDTO.getRecipes().get(2).getDetails().size());

        IntSummaryStatistics intSummaryStatistics = checkRecipeInputDTO.getRecipes().stream().mapToInt(new ToIntFunction<RecipeDTO>() {
            @Override
            public int applyAsInt(RecipeDTO value) {
                return value.getDetails().size();
            }
        }).summaryStatistics();

        System.out.println(intSummaryStatistics.getMax());

        Optional<RecipeDTO> max = checkRecipeInputDTO.getRecipes().stream().max(new Comparator<RecipeDTO>() {
            @Override
            public int compare(RecipeDTO o1, RecipeDTO o2) {
                return Math.max(o1.getDetails().size(), o2.getDetails().size());
            }
        });*/
//        System.out.println("max:" + max.);

        futureTest();


        //两个CompletableFuture执行异步任务
//        CompletableFuture<String> cfQuerySina = CompletableFuture.supplyAsync(new Supplier<String>() {
//            @Override
//            public String get() {
//                for (int i = 0; i < 50; i++) {
//                    try {
//                        Thread.sleep(100);
//                        System.out.println("threadi:" + Thread.currentThread() + ", i:" + i);
//
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//
//                return "str111";
//            }
//        });
//        CompletableFuture<String> cfQuery163 = CompletableFuture.supplyAsync(new Supplier<String>() {
//            @Override
//            public String get() {
//                for (int i = 0; i < 50; i++) {
//                    try {
//                        Thread.sleep(100);
//                        System.out.println("threadj:" + Thread.currentThread() + ", j:" + i);
//
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//                return "str222";
//            }
//        });
//        //使用anyOf合并为一个新的CompletableFuture
////        CompletableFuture.allOf(cfQuerySina, cfQuery163).thenApply(new Function<Void, Object>() {
////            @Override
////            public Object apply(Void unused) {
////                return unused;
////            }
////        });
//
////        Thread.sleep(10000);
//
//        CompletableFuture<Void> combindFuture = CompletableFuture.allOf(cfQuerySina, cfQuery163);
//        String s = cfQuerySina.get();
//        String s1 = cfQuery163.get();
//        System.out.println("get---:" + s + ", " + s1);
//        try {
//            combindFuture.get();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        } catch (ExecutionException e) {
//            e.printStackTrace();
//        }
    }


    public static void futureTest() throws ExecutionException, InterruptedException {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                for (int i = 0; i < 100; i++) {
                    Thread.sleep(30);
                    System.out.println("i==" + i);
                }
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("future1 finished!");
            return "future1 finished!";
        });
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                for (int i = 0; i < 100; i++) {
                    Thread.sleep(30);
                    System.out.println("j==" + i);
                }
            } catch (Exception e) {

            }
            System.out.println("future2 finished!");
            return "future2 finished!";
        });
        CompletableFuture<Void> combindFuture = CompletableFuture.allOf(future1, future2);
        try {
            combindFuture.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("future1: " + future1.isDone() + " future2: " + future2.get());
    }
}
